#include "ccompassprotocol.h"
#include <QDebug>
#include <QMessageBox>
CCompassProtocol::CCompassProtocol ( QObject* parent ) :
    QObject ( parent )
{
    m_serial = new CXSerialPort ( "/dev/ttymxc1", 9600 );
   // m_serial = new CXSerialPort ( "/dev/ttyUSB0", 9600 );
    m_readtimer = new QTimer ( this );
    connect ( m_readtimer, SIGNAL ( timeout() ), this, SLOT ( readSerial() ) );
    m_readtimer->start ( 50 );
    m_onlinetimeout = new QTimer ( this );
    connect ( m_onlinetimeout, SIGNAL ( timeout() ), this, SLOT ( pushCommand () ) );
    m_onlinetimeout->start ( 3000 );
    m_serialdatabuffer = new QByteArray();
    m_serialdatabuffer->clear();
    registerFloor = new QVector<int>;
    isPicking=false;
    pickCount=0;
}

void CCompassProtocol::pushCommand ( int cmd )//key pressed
{  
    if( (cmd>=1)&&(cmd<=8) )
    {
        QByteArray newprotocol1;
        newprotocol1.resize ( 6 );
        newprotocol1[0] = 0x02;
        newprotocol1[1] = 'F';
        newprotocol1[2] = 0x30;
        newprotocol1[3] = 0x30+cmd;//N楼
        newprotocol1[4] = 0x30;//校验F待定
        newprotocol1[5] = 0x03;
        QString debugstr;
        debugstr = newprotocol1.toHex();
        qDebug() << debugstr;
        m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==9)
    {
            //开门协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'O';
            newprotocol1[2] = '1';//开门
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==10)
    {
            //关门协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'L';
            newprotocol1[2] = '1';//关门
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==11)
    {
            //风扇协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'B';
            newprotocol1[2] = '1';//风扇开
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==12)
    {
            //风扇协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'B';
            newprotocol1[2] = '0';//风扇关
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==13)
    {
            //照明协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'E';
            newprotocol1[2] = '1';//照明开
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==14)
    {
            //照明协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'E';
            newprotocol1[2] = '0';//照明关
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==15)
    {
            //警铃协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'J';
            newprotocol1[2] = '1';//警铃开
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==16)
    {
            //警铃协议
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'J';
            newprotocol1[2] = '0';//警铃关
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==17)
    {
            //（1） 轿厢型号协议: ‘1’ 主操纵厢,‘2’ 后操纵厢, ‘3’ 残疾人操纵厢,‘4’ 副操纵厢
            //（2） 选层器在刚初始化后立即发送，收到转换板回复后停止发送；
            //（3） 参数K02有改变后立即发送，收到转换板回复后停止发送；
            QByteArray newprotocol1;
            newprotocol1.resize ( 5 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'C';
            newprotocol1[2] = '1';//主操纵厢
            newprotocol1[3] = 0x30;//校验F待定
            newprotocol1[4] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }
    else if(cmd==18)
    {
            //软件版本查询协议，
            QByteArray newprotocol1;
            newprotocol1.resize ( 4 );
            newprotocol1[0] = 0x02;
            newprotocol1[1] = 'W';
            newprotocol1[2] = 0x30;//校验F待定
            newprotocol1[3] = 0x03;
            QString debugstr;
            debugstr = newprotocol1.toHex();
            qDebug() << debugstr;
            m_serial->flushBuffer (  newprotocol1 );
    }

}

void CCompassProtocol::pushCommand ()//heart bit
{
    QByteArray tmpbuf;
    tmpbuf.resize ( 19 );
    tmpbuf[0] = 0xF0;
    tmpbuf[1] = 0x30;
    tmpbuf[2] = 0x30;
    tmpbuf[3] = 0x35;
    
    //无用信息
    for ( int i = 4; i < 17; i++ )
    {
        tmpbuf[i] = 0x30;
    }
        //写入校验码
    unsigned int  m_ucTemp = 0;
    
    for ( int i = 1; i < 17; i++ )
    {
        m_ucTemp ^= tmpbuf[i];
    }
    
    m_ucTemp &= 0x0f;
    char asc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D','E', 'F'};
    tmpbuf[17] = asc[m_ucTemp];
    //qDebug() << asc[m_ucTemp];
    //qDebug() << tmpbuf[17];
    //结束符号
    tmpbuf[18] = 0xF1;
    QString debugstr;
    debugstr = tmpbuf.toHex();
    //qDebug() <<"powerData:"<< debugstr;
    //QMessageBox::information ( NULL, "message", debugstr);
    m_serial->flushBuffer ( tmpbuf );
}

bool CCompassProtocol::pickCommand()
{
    pickCount++;
    //qDebug()<<"pickCount:"<<pickCount;
    isPicking=true;
    if(findNextHeader()==0)
    {
          isPicking =false;
          return true;
    }
    //接受到的是楼层信息
    if ( findNextHeader() == 1 )
    {
       //qDebug() << "have date 1";
       // qDebug() << m_serialdatabuffer->data();
       // qDebug() << m_serialdatabuffer->toHex();
        //校验
        unsigned int  m_ucTemp = 0;
        
        for ( int i = 1; i < 8; i++ )
        {
            m_ucTemp ^= ( *m_serialdatabuffer ) [i];
        }
        
        m_ucTemp &= 0x0f;
        char ascUP[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D','E','F'};
        char ascDown[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd','e','f'};
        
        if ( ascUP[m_ucTemp] != ( *m_serialdatabuffer ) [8] &&
                ascDown[m_ucTemp] != ( *m_serialdatabuffer ) [8] )
        {
            //qDebug() << "DataCheak_err";
            m_serialdatabuffer->remove ( 0, 12 );
            return true;
        }
        else
        {
            //qDebug() << "DataCheak_success";
        }
        
        //楼层范围系数
        QString floorStateData ( m_serialdatabuffer->mid ( 1, 7 ) );
       // qDebug() << floorStateData.toLatin1().toHex();
        emit floorState ( floorStateData );
        //emit floorState ( floorStateData.toStdString().c_str() );
        //qDebug()<<"floorStateData"<<floorStateData;
        
//        emit online();
//        m_onlinetimeout->stop();
//        m_onlinetimeout->start ( 3000 );
        m_serialdatabuffer->remove ( 0, 12 );
    }
    
    //接受登记信息
    if ( findNextHeader() == 2 )
    {
   //      qDebug() << "have date 2";
   //      qDebug() << m_serialdatabuffer->data();
   //      qDebug() << m_serialdatabuffer->toHex();
   //      qDebug() << m_serialdatabuffer->mid(0,18).toHex();
        //校验
        unsigned int  m_ucTemp = 0;
        
        for ( int i = 1; i < 17; i++ )
        {
            m_ucTemp ^= ( *m_serialdatabuffer ) [i];
        }
        
        m_ucTemp &= 0x0f;
        char asc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D','E','F'};
        
        if ( asc[m_ucTemp] != ( *m_serialdatabuffer ) [17] )
        {
            qDebug() << "DataCheak_err";
            m_serialdatabuffer->remove ( 0, 19 );
            return true;
        }
        else
        {
           // qDebug() << "DataCheak_success";
        }
        
        //楼层范围系数
        registerFloor->clear();
        int tempData = -1;
        int factor = -1;
        unsigned int iddate = ( *m_serialdatabuffer ) [1] ;
        tempData = getDecimalfromByte ( iddate );
        
        if ( tempData < 0 || tempData > 15 )
        {
            //qDebug() << "factor_err";
            m_serialdatabuffer->remove ( 0, 19 );
            return true;
        }
        else
        {
            factor = tempData;
        }
        
        registerFloor->push_back ( factor );
        //楼层信息
        unsigned int cmddata1_4 = ( *m_serialdatabuffer ) [13];
        unsigned int cmddata5_8 = ( *m_serialdatabuffer ) [14];
        unsigned int cmddata9_12 = ( *m_serialdatabuffer ) [15];
        unsigned int cmddata13_16 = ( *m_serialdatabuffer ) [16];
        tempData = getDecimalfromByte ( cmddata1_4 );
        
        if ( tempData < 0 || tempData > 15 )
        {
            qDebug() << "cmddata1_4_err";
            m_serialdatabuffer->remove ( 0, 19 );
            return true;
        }
        else
        {
            for ( int i = 1; i <= 4; i++ )
            {
                int  mo_tempData = tempData % 2;
                tempData = tempData / 2;
                registerFloor->push_back ( mo_tempData );
            }
        }
        
        tempData = -1;
        tempData = getDecimalfromByte ( cmddata5_8 );
        
        if ( tempData < 0 || tempData > 15 )
        {
            qDebug() << "cmddata5_8_err";
            m_serialdatabuffer->remove ( 0, 19 );
            return true;
        }
        else
        {
            for ( int i = 1; i <= 4; i++ )
            {
                int  mo_tempData = tempData % 2;
                tempData = tempData / 2;
                registerFloor->push_back ( mo_tempData );
            }
        }
        
        tempData = -1;
        tempData = getDecimalfromByte ( cmddata9_12 );
        
        if ( tempData < 0 || tempData > 15 )
        {
            qDebug() << "cmddata9_12_err";
            m_serialdatabuffer->remove ( 0, 19 );
            return true;
        }
        else
        {
            for ( int i = 1; i <= 4; i++ )
            {
                int  mo_tempData = tempData % 2;
                tempData = tempData / 2;
                registerFloor->push_back ( mo_tempData );
            }
        }
        
        tempData = -1;
        tempData = getDecimalfromByte ( cmddata13_16 );
        
        if ( tempData < 0 || tempData > 15 )
        {
            qDebug() << "cmddata13_16_err";
            m_serialdatabuffer->remove ( 0, 19 );
            return true;
        }
        else
        {
            for ( int i = 1; i <= 4; i++ )
            {
                int  mo_tempData = tempData % 2;
                tempData = tempData / 2;
                registerFloor->push_back ( mo_tempData );
            }
        }
        
        QString qdebugResgiterFloor;
        
        for ( int i = 0; i < registerFloor->count(); i++ )
        {
            qdebugResgiterFloor += QString::number ( ( *registerFloor ) [i] ) + " ";
        }
        
//       qDebug() << qdebugResgiterFloor;
//        emit assignLift ( registerFloor );
//        emit online();
//        m_onlinetimeout->stop();
//        m_onlinetimeout->start ( 3000 );
        getregflr();
        m_serialdatabuffer->remove ( 0, 19 );
    }

    return true;
}

void CCompassProtocol::getregflr()
{
    //空指针
    if ( registerFloor == 0 )
    {
        qDebug() << "process registerFloor err:registerFloor=0";
        return ;
    }
    else if ( registerFloor->count() == 17 ) //检查数量
    {
        for ( QVector<int>::iterator ite = registerFloor->begin() + 1 ; ite != registerFloor->end(); ite++ )
        {

            int num = ite - registerFloor->begin();

            int mapNum = num + ( * ( registerFloor->begin() ) ) * 16;


            mapNum = mapNum - 1;


            if ( *ite == 1 )
            {
                switch ( mapNum )
                {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                        emit regf(mapNum);
                        break;
                }

            }

            if (  *ite == 0 )
            {
                switch ( mapNum )
                {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                        emit unregf(mapNum);
                        break;

                }
            }



        }
    }

}

int CCompassProtocol::findNextHeader()
{
    while ( m_serialdatabuffer->size() >= 12 )
    {
        if ( m_serialdatabuffer->at ( 0 ) == 0x02 && m_serialdatabuffer->at ( 11 ) == 0x03 )
        {
            return 1;
        }
        if ( m_serialdatabuffer->size() < 19 && m_serialdatabuffer->size() > 12)
        {
            if( m_serialdatabuffer->at ( 0 ) == 0xF0)
                {
                    return 0;
                }
        }
        if ( m_serialdatabuffer->size() >= 19 &&
                m_serialdatabuffer->at ( 0 ) == 0xF0 &&
                m_serialdatabuffer->at ( 18 ) == 0xF1 )
        {
            return 2;
        }
        
        m_serialdatabuffer->remove ( 0, 1 );
    }
    
    return 0;
}

//    bool CCompassProtocol::compassRegistFloor(unsigned char  currentfloor, unsigned char  destfloor, int icid)
//    {
//        QByteArray cmdstr(8,0);
//        cmdstr[0] = currentfloor;
//        cmdstr[1] = destfloor;
//
//        //pushCommand(0x00018000,cmdstr);
//        qDebug("output command: 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
//               cmdstr.at(0),cmdstr.at(1),cmdstr.at(2),cmdstr.at(3),cmdstr.at(4),cmdstr.at(5),cmdstr.at(6),cmdstr.at(7));
//    }

void CCompassProtocol::readSerial()
{
    QByteArray tmpserialdata;
    tmpserialdata.clear();
    m_serial->pushBuffer ( tmpserialdata );
     
    if ( tmpserialdata.size() > 0 )
    {
        m_serialdatabuffer->append ( tmpserialdata );
        
        if(isPicking==false) 
        {
            do {
            pickCommand();
            } while (isPicking);
        }       
    }
}

int CCompassProtocol::getDecimalfromByte ( unsigned int iddata )
{
    //楼层系数
    int i = -1;
    
    switch ( iddata )
    {
        case 0x30:
            i = 0;
            break;
        case 0x31:
            i = 1;
            break;
        case 0x32:
            i = 2;
            break;
        case 0x33:
            i = 3;
            break;
        case 0x34:
            i = 4;
            break;
        case 0x35:
            i = 5;
            break;
        case 0x36:
            i = 6;
            break;
        case 0x37:
            i = 7;
            break;
        case 0x38:
            i = 8;
            break;
        case 0x39:
            i = 9;
            break;
        case 0x41:
            i = 10;
            break;
        case 0x42:
            i = 11;
            break;
        case 0x43:
            i = 12;
            break;
        case 0x44:
            i = 13;
            break;
        case 0x45:
            i = 14;
            break;
        case 0x46:
            i = 15;
            break;
        case 0x61:
            i = 10;
            break;
        case 0x62:
            i = 11;
            break;
        case 0x63:
            i = 12;
            break;
        case 0x64:
            i = 13;
            break;
        case 0x65:
            i = 14;
            break;
        case 0x66:
            i = 15;
            break;
        default :
            i = -1;
            break;
    }
    
    return i;
}


